<?php

namespace api\modules\v1\forms\rbac;

use common\models\rbac\Menu;
use common\models\rbac\Action;
use Yii;
use yii\base\Model;

/**
 * Class ActionForm
 * @package api\modules\v1\forms\rbac
 */
class ActionForm extends Model
{
    /**
     * @var int $member_id 用户ID
     * @var int $id 动作ID
     * @var int $menu_id 菜单ID
     * @var string $name 动作名
     * @var string $flag 动作路由
     * @var int $status 状态
     * @var int $sort 排序
     */
    public $member_id;
    public $id;
//    public $module_id;
    public $menu_id;
    public $name;
    public $flag;
    public $status;
    public $sort;

    /**
     * @var Action $_action
     * @var Menu $_menu
     */
    protected $_action;
    protected $_menu;


    public function rules()
    {
        return [
            // 参数验证
            [['member_id', 'name', 'menu_id', 'flag', 'status'], 'required', 'message' => '{attribute}不能为空', 'on' => ['create']],
            [['member_id', 'id', 'name', 'menu_id', 'flag', 'status'], 'required', 'message' => '{attribute}不能为空', 'on' => ['edit']],
            [['member_id', 'id'], 'required', 'message' => '{attribute}不能为空', 'on' => ['delete']],

            [['member_id'], 'checkMemberId', 'skipOnEmpty' => false, 'on' => ['create', 'edit', 'delete']],
            [['id'], 'checkId', 'skipOnEmpty' => false, 'on' => ['edit', 'delete']],
            [['name'], 'checkName', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
//            [['module_id'], 'checkModuleId', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
            [['menu_id'], 'checkMenuId', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
            [['flag'], 'checkFlag', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
            [['sort'], 'checkSort', 'skipOnEmpty' => true, 'on' => ['create', 'edit']],
            [['status'], 'checkStatus', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
        ];
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();

        // 新增
        $scenarios['create'] = ['member_id', 'name', 'menu_id', 'flag', 'sort', 'status'];

        // 编辑
        $scenarios['edit'] = ['member_id', 'id', 'name', 'menu_id', 'flag', 'sort', 'status'];

        // 删除
        $scenarios['delete'] = ['member_id', 'id'];

        return $scenarios;
    }

    /**
     * @return array
     */
    public function attributeLabels()
    {
        return [
            'member_id' => '用户ID',
            'id' => '动作ID',
            'name' => '动作名称',
//            'module_id' => '模块名称',
            'menu_id' => '菜单名称',
            'flag' => '路由',
            'sort' => '排序',
            'status' => '状态',
        ];
    }

    /**
     * 检验用户ID
     * @param $attribute
     * @return void
     */
    public function checkMemberId($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

//        $account = Member::findOne($this->member_id);
        /*if ($account->is_super != Member::IS_SUPER_YES) {
            $this->addError($attribute, '非超管，无权限操作');
            return true;
        }*/
    }

    /**
     * 检验动作ID
     * @param $attribute
     * @return void
     */
    public function checkId($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        $action = $this->getAction();
        if (!$action) {
            $this->addError($attribute, '动作不存在');
            return;
        }

        if ($action->status == Action::STATUS_DELETE) {
            $this->addError($attribute, '动作已删除');
            return;
        }

//        if (($this->getScenario() == 'edit' && $this->status == Action::STATUS_INVALID)
//            || $this->getScenario() == 'delete') {
//            $rolePermission = RolePermission::findOne([
//                'permission_id' => $action->id,
//                'permission_type' => RolePermission::PERMISSION_TYPE_ACTION,
//            ]);
//            if ($rolePermission) {
//                $this->addError($attribute, "该动作存在角色绑定，请先解除绑定");
//                return;
//            }
//        }
    }

    /**
     * 校验动作名称
     * @param $attribute
     * @return void
     */
    public function checkName($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        $len = mb_strlen($this->name);
        if ($len > 20) {
            $this->addError($attribute, '动作名称过长，最多20个字');
            return;
        }

        // 是否检验
        $isCheck = true;
        if ($this->getScenario() == 'edit') {
            $action = $this->getAction();
            // 动作参数未改变【跳过】
            if ($action->name == $this->name && $action->flag == $this->flag && $action->menu_id == $this->menu_id) {
                $isCheck = false;
            }
        }

        if ($isCheck) {
            $actionInfo = Action::findOne([
                'name' => $this->name,
                'flag' => $this->flag,
                'menu_id' => $this->menu_id,
                'status' => [Action::STATUS_INVALID, Action::STATUS_ENABLE],
            ]);

            if ($actionInfo) {
                $this->addError($attribute, "动作【{$this->name}】已存在");
                return;
            }
        }
    }

    /**
     * 校验模块ID
     *
     * @param $attribute
     */
//    public function checkModuleId($attribute)
//    {
//        if ($this->hasErrors()) {
//            return true;
//        }
//
//        $module = Module::findOne($this->module_id);
//        if (empty($module)) {
//            $this->addError($attribute, '模块不存在');
//            return true;
//        }
//
//        if ($module->status != Module::STATUS_ENABLE) {
//            $this->addError($attribute, '模块未启用');
//            return true;
//        }
//    }

    /**
     * 校验菜单ID
     * @param $attribute
     * @return void
     */
    public function checkMenuId($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        $menu = $this->getMenu();
        if (empty($menu)) {
            $this->addError($attribute, '菜单不存在');
            return;
        }

        if ($menu->status != Menu::STATUS_ENABLE) {
            $this->addError($attribute, '菜单未启用');
            return;
        }

//        if ($menu->module_id != $this->module_id) {
//            $this->addError($attribute, '非当前模块菜单');
//            return;
//        }
    }

    /**
     * 校验动作路由
     * @param $attribute
     * @return void
     */
    public function checkFlag($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        $len = strlen($this->flag);
        if ($len > 80) {
            $this->addError($attribute, '动作路由过长，最多80个字节');
            return;
        }
    }

    /**
     * 校验动作排序
     * @param $attribute
     * @return void
     */
    public function checkSort($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        if ($this->sort < 0) {
            $this->addError($attribute, '排序值不能小于0');
            return;
        }
    }

    /**
     * 校验动作状态
     * @param $attribute
     * @return void
     */
    public function checkStatus($attribute): void
    {
        if ($this->hasErrors()) {
            return;
        }

        if (!in_array($this->status, [Action::STATUS_INVALID, Action::STATUS_ENABLE])) {
            $this->addError($attribute, "非法状态");
            return;
        }
    }

    /**
     * 获取动作信息
     * @return Action|null
     */
    public function getAction(): ?Action
    {
        if (empty($this->_action)) {
            $this->_action = Action::findOne($this->id);
        }

        return $this->_action;
    }

    /**
     * 获取菜单信息
     * @return Menu|null
     */
    public function getMenu(): ?Menu
    {
        if (empty($this->_menu)) {
            $this->_menu = Menu::findOne($this->menu_id);
        }

        return $this->_menu;
    }
}
